package com.sample.transitiondemo;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.facebook.common.util.UriUtil;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.DraweeHolder;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.util.HashMap;

/**
 * Created by gouzhun on 2016/4/2.
 */
public class FrescoDiamondImageView extends View {

    private DraweeHolder mDraweeHolder;
    private boolean mInitialised = false;

    private String TAG = "DIAMOND";
    private static final Xfermode MASK_XFERMODE;
    private Bitmap mask;
    private static String ptsStr = "0,0.5,0.5,1,1,0.5,0.5,0";
    private Paint paint;
    private int mBorderWidth = 10;
    private int mBorderColor = Color.parseColor("#f2f2f2");
    Paint mBorderPaint;
    private Path shapePath;
    private String pathStr;
    private boolean isDrawBorder = true;
    private boolean isRoundCorner = true;
    private static HashMap<String, Bitmap> maskMap;
    Rect dest = null;

    static {
        PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;
        MASK_XFERMODE = new PorterDuffXfermode(localMode);
    }

    private boolean isSetBound;

    public FrescoDiamondImageView(Context context) {
        super(context);
        init(context);
    }

    public FrescoDiamondImageView(Context paramContext, AttributeSet paramAttributeSet) {
        this(paramContext, paramAttributeSet, 0);
    }

    public FrescoDiamondImageView(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {

        super(paramContext, paramAttributeSet, paramInt);
        TypedArray a = paramContext.obtainStyledAttributes(paramAttributeSet, R.styleable.CustomImage);
        mBorderColor = a.getColor(R.styleable.CustomImage_border_color, mBorderColor);
        final int defalut = (int) (2 * paramContext.getResources().getDisplayMetrics().density + 0.5f);
        mBorderWidth = a.getDimensionPixelOffset(R.styleable.CustomImage_border_width, defalut);
        isDrawBorder = a.getBoolean(R.styleable.CustomImage_is_draw_border, true);
        isRoundCorner = a.getBoolean(R.styleable.CustomImage_is_round_corner, false);
        pathStr = a.getString(R.styleable.CustomImage_shapePts);

        a.recycle();

        init(paramContext);
    }

    @SuppressWarnings("unchecked")
    private void init(Context context) {
        if (!mInitialised) {
            GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources()).build();
            mDraweeHolder = (DraweeHolder) DraweeHolder.create(hierarchy, context);
            mDraweeHolder.getTopLevelDrawable().setCallback(this);
            mInitialised = true;
        }
        if (pathStr == null || pathStr.equalsIgnoreCase("")) {
            pathStr = ptsStr;
        }
    }

    @Override
    public void onStartTemporaryDetach() {
        super.onStartTemporaryDetach();
        mDraweeHolder.onDetach();
    }

    @Override
    public void onFinishTemporaryDetach() {
        super.onFinishTemporaryDetach();
        mDraweeHolder.onAttach();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mDraweeHolder.onAttach();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mDraweeHolder.onDetach();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int x = (int) event.getX();
        int y = (int) event.getY();
        if (isTouchPointInTransparent(x, y)) {
            return false;
        } else {
            return super.onTouchEvent(event);
        }


    }

    /**
     * @param x
     * @param y
     * @return 判断点击区域是否在透明区域
     */
    public boolean isTouchPointInTransparent(int x, int y) {
        int paddingLeft = this.getPaddingLeft();
        int paddingTop = this.getPaddingTop();
        int viewWidth = this.getWidth();
        int viewHeight = this.getHeight();
        if (mask == null) {
            return false;
        }

        int imageWidth = mask.getWidth();
        int imageHeight = mask.getHeight();

        int locationInBitmapX = (x - paddingLeft) * imageWidth / viewWidth;
        int locationInBitmapY = (y - paddingTop) * imageHeight / viewHeight;
        if (locationInBitmapX >= imageWidth || locationInBitmapY >= imageHeight || locationInBitmapX < 0 || locationInBitmapY < 0) {
            return false;
        }
        int pixel = mask.getPixel(locationInBitmapX, locationInBitmapY);

//        Log.e("mcoy", "x is " + x);
//        Log.e("mcoy", "y is " + y);
//        Log.e("mcoy", "imageHeight is " + imageHeight);
//        Log.e("mcoy", "imageWidth is " + imageWidth);
//        Log.e("mcoy", "viewWidth is " + viewWidth);
//        Log.e("mcoy", "viewHeight is " + viewHeight);
//        Log.e("mcoy", "locationInBitmapX is " + locationInBitmapX);
//        Log.e("mcoy", "locationInBitmapY is " + locationInBitmapY);
//        Log.e("mcoy", "pixel is " + pixel);

        return pixel == 0;
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        if (who == mDraweeHolder.getTopLevelDrawable()) {
            return true;
        } else {
            super.verifyDrawable(who);
        }
        return true;
    }

    public void setImageURL(String url) {
        try {
            if (url != null && !url.equalsIgnoreCase("")) {
                setImageURI(Uri.parse(url));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setImageURI(Uri uri) {

        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri)
                .setAutoRotateEnabled(true)
                .build();

        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setImageRequest(imageRequest)
                .setOldController(mDraweeHolder.getController())
                .build();

        mDraweeHolder.setController(controller);
    }

    public void setImageResourcesId(int resId) {
        Uri uri = new Uri.Builder()
                .scheme(UriUtil.LOCAL_RESOURCE_SCHEME) // "res"
                .path(String.valueOf(resId))
                .build();
        // uri looks like res:/123456789
        setImageURI(uri);
    }

    @Override
    protected void onDraw(Canvas paramCanvas) {
        int width = getWidth();
        int height = getHeight();

        final Drawable localDrawable = mDraweeHolder.getHierarchy().getTopLevelDrawable();
        if (!isSetBound) {
            /** 设置drawable的大小 */
            localDrawable.setBounds(0, 0, width, height);
            isSetBound = true;
            dest = new Rect(0, 0, width, height);
        }

        if (localDrawable == null)
            return;
        if (localDrawable instanceof NinePatchDrawable) {
            return;
        }
        if (this.paint == null) {
            final Paint localPaint = new Paint();
            localPaint.setFilterBitmap(false);
            localPaint.setAntiAlias(true);
            localPaint.setXfermode(MASK_XFERMODE);
            this.paint = localPaint;
        }

        /** 保存layer */
        int layer = 0;
        if (!isInEditMode()) {
            layer = paramCanvas.saveLayer(0.0F, 0.0F, width, height, null, Canvas.ALL_SAVE_FLAG);
        }


        /** 将drawable绑定到bitmap(this.mask)上面（drawable只能通过bitmap显示出来） */
        localDrawable.draw(paramCanvas);
        if ((this.mask == null) || (this.mask.isRecycled())) {
            this.mask = DrawUtils.createDiamondBitmap(pathStr, width, height, isRoundCorner);
        }
        /** 将bitmap画到canvas上面 */
        Rect src = new Rect(0, 0, mask.getWidth(), mask.getHeight());

        paramCanvas.drawBitmap(this.mask, src, dest, this.paint);
        /** 将画布复制到layer上 */
        if (!isInEditMode() && isDrawBorder) {
            paramCanvas.restoreToCount(layer);
            drawBorder(paramCanvas, width, height);
        }
    }


    /**
     * 绘制最外面的边框
     *
     * @param canvas
     * @param width
     * @param height
     */
    private void drawBorder(Canvas canvas, final int width, final int height) {
       /* if (mBorderWidth == 0) {
            return;
        }*/

        if (mBorderPaint == null) {
            mBorderPaint = new Paint();
            mBorderPaint.setStyle(Paint.Style.STROKE);
            mBorderPaint.setAntiAlias(true);
            mBorderPaint.setColor(mBorderColor);
            mBorderPaint.setStrokeWidth(mBorderWidth);
            if (isRoundCorner) {
                mBorderPaint.setPathEffect(new CornerPathEffect(8));
            }
        }
        /**
         * 坐标x：view宽度的一般 坐标y：view高度的一般 半径r：因为是view的宽度-border的一半
         */
        if (shapePath == null) {
            shapePath = DrawUtils.createPath(width, height, pathStr);

        }
        canvas.drawPath(shapePath, mBorderPaint);
        canvas = null;
        //https://git.oschina.net/axeman/TranslationDe.git
    }
}
